Lambda@Edgeを利用してすべてのSet-CookieにSecureとHttpOnlyを付ける
最近会社においてあるグランツーリスモをやっているもこ@札幌オフィスです。
Lambda@Edgeを利用してオリジンから送られる Set-Cookie
を書き換えて、送信されるCookie全てにSecure属性とHttOnlyを付けてみました。
コード
今回利用したコードはこんな形になっています。
exports.handler = (event, context, callback) => { const response = event.Records[0].cf.response; for (const cookie of response.headers['set-cookie']) { cookie.value += "; Secure; HttpOnly" } callback(null, response); }
利用方法
オリジンから送信されてくる情報を書き換える必要があるため、CloudFrontイベントは"オリジンレスポンス"を利用します。
また、CloudFrontの設定、「Forward Cookies」をAllなどに変更する必要があります。(キャッシュのヒット率は下がります。)
関数を作成し
上記コードを貼り付け
ロールを作成し、保存します。
上のアクションから「Lambda@Edgeへのデプロイ」を選択し、
デプロイ先のCloudFrontを選択し、CloudFrontイベントををオリジンレスポンスに変更します。
User <-> CloudFront(Lambda@Edge) <-> ALB <-> EC2
のような環境を作成し、
適当なCookieを投げるようなアプリケーションを作り、EC2上に起動しました。
const express = require('express') const app = express(); app.get('/', (req, res) => { res .cookie('hoge', 'hoge') .cookie('test', 'test') .status(200).send('OK'); }) app.listen(80)
ALBを叩いてSet-Cookieヘッダーが追加されているのを確認します。
$ curl -I xxxxx-xxxxxxxxx.ap-northeast-1.elb.amazonaws.com HTTP/1.1 200 OK Date: Fri, 20 Sep 2019 8:14:32 GMT Content-Type: text/html; charset=utf-8 Content-Length: 2 Connection: keep-alive X-Powered-By: Express Set-Cookie: hoge=hoge; Path=/ Set-Cookie: test=test; Path=/ ETag: W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc"
Lambda@EdgeのCloudFrontへのデプロイが終わり、curlで叩いてみると、正常に ; Secure; HttpOnly
が追加されているのを確認出来ます。
$ curl -I http://xxxxx.cloudfront.net HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 2 Connection: keep-alive Server: CloudFront Date: Fri, 20 Sep 2019 8:12:23 GMT X-Powered-By: Express Set-Cookie: hoge=hoge; Path=/; Secure; HttpOnly Set-Cookie: test=test; Path=/; Secure; HttpOnly ETag: W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc" X-Cache: Miss from cloudfront Via: 1.1 171d3bd7ed02f868a62075a1caaa7993.cloudfront.net (CloudFront) X-Amz-Cf-Pop: NRT53 X-Amz-Cf-Id: Fm3nsyZ2_N7viWjvfQ_DSjz9B9lR45Rz0JHQBrAgg3qHBmZtSIf9Ag==
また、HttpOnlyの効果により document.cookie
の取得も出来なくなっているのが確認できます。
まとめ
CloudFrontのオリジンレスポンスを利用すると、アプリケーション側ではなくLambda@Edge側で強制的にヘッダーを書き換えることが出来るので、とても便利です。
Lambda@Edgeの使い方次第ではサーバーレスではない環境に対してもサーバーレスチックな使い方が出来ると思います。
誰かのお役に立てれば幸いです。